﻿namespace Nomo.UnityCoreModule
{
    /// <summary>
    /// 用于判断一个点是否位于多边形内的帮助器。
    /// </summary>
    public static class ContainmentHelper
    {
        /// <summary>
        /// 返回一个值，这个值指示 <paramref name="localPoint"/> 点是否被包含在由 <paramref name="vertices"/> 顺序连接而成的多边形内。
        /// </summary>
        /// <param name="localPoint">点的局部坐标。</param>
        /// <param name="vertices">用于表示一个多边形的顶点序列。</param>
        /// <returns><paramref name="localPoint"/> 被包含在由 <paramref name="vertices"/> 顺序连接而成的多边形内吗？</returns>
        public static bool Contains(UnityEngine.Vector2 localPoint, System.Collections.Generic.IReadOnlyList<UnityEngine.Vector2> vertices)
        {
            return (RayCrossCount(localPoint, vertices) & 1) == 1;
        }

        private static int RayCrossCount(UnityEngine.Vector2 localPoint, System.Collections.Generic.IReadOnlyList<UnityEngine.Vector2> vertices)
        {
            var rayCrossCount = 0;

            for (int i = 0, count = vertices.Count; i < count; i++)
            {
                var v1 = vertices[i];
                var v2 = vertices[(i + 1) % count];

                if (v1.y <= localPoint.y && localPoint.y < v2.y || v1.y > localPoint.y && localPoint.y >= v2.y)
                {
                    if (localPoint.x < v1.x + (localPoint.y - v1.y) / (v2.y - v1.y) * (v2.x - v1.x))
                    {
                        ++rayCrossCount;
                    }
                }
            }

            return rayCrossCount;
        }
    }
}
